package com.jindun.paper.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.jindun.paper.dao.BagOrderItemRepository;
import com.jindun.paper.dao.BoxOrderItemRepository;
import com.jindun.paper.dao.ClientRepository;
import com.jindun.paper.dao.OrderRepository;
import com.jindun.paper.model.BagOrderItem;
import com.jindun.paper.model.BoxOrderItem;
import com.jindun.paper.model.Client;
import com.jindun.paper.model.Order;
import com.jindun.paper.service.AmountCalculator;
import com.jindun.paper.vo.MonthlyAmountVo;

@Service
public class AmountCalculatorImpl implements AmountCalculator {
	@Autowired
	private OrderRepository bagOrderRepository;

	@Autowired
	private OrderRepository boxOrderRepository;

	@Autowired
	private BagOrderItemRepository bagOrderItemRepository;

	@Autowired
	private BoxOrderItemRepository boxOrderItemRepository;

	@Autowired
	private MonthlyCalculator monthlyCalculator;

	@Autowired
	private ClientRepository clientRepository;

	@Override
	public MonthlyAmountVo calcMonthlyAmount(Client client) {
		Date[] dates = this.monthlyCalculator.calc(client.getClientType()
				.getMonthlyBegin(), new Date());
		double quotaAmount = client.getClientType().getLimitation();
		double amount = this.calcOrderAmount(client, dates[0], dates[1]);
		return new MonthlyAmountVo(client, quotaAmount, amount);
	}

	public double calcOrderAmount(Client client, Date startDate,
			Date endDate) {
		List<Order> bagOrders = this.bagOrderRepository
				.findByClientAndStatusAndCreateDateBetween(client,
						Order.OrderStatus.CONFIRMED.getCode(), startDate,
						endDate);
		double amount = 0.0;
		for (Order bagOrder : bagOrders) {
			
			 amount += calcOrderAmount(bagOrder);
			
			
		}
		return amount;
	}
	
	

	@Override
	public double calcOrderAmount(Order bagOrder) {
		double amount = 0.0;
		if (Order.OrderType.BAG.getCode().equals(bagOrder.getOrderType())) {
			amount += this.calcBagOrderAmount(bagOrder);
		} else {
			amount += this.calcBoxOrderAmount(bagOrder);
		}
		return amount;
	}

	public double calcBagOrderAmount(Order bagOrder) {

		double amount = 0.0;

		List<BagOrderItem> items = bagOrderItemRepository
				.findByBagOrderOrderById(bagOrder);

		for (BagOrderItem item : items) {
			amount += this.calcBagOrderItemAmount(item);
		}

		return amount;

	}

	private double calcBagOrderItemAmount(BagOrderItem item) {
		double amount = 0.0;
		amount += (item.getPrice()
				* ((item.getExactStubQty() - item.getExclustionStubQty()) + item
						.getAdditionalBagQty()) * item.getExcludedAvgPerStub())
				+ item.getAdditionalAmount();
		return amount;
	}



	public double calcBoxOrderAmount(Order boxOrder) {

		double amount = 0.0;
		List<BoxOrderItem> items = this.boxOrderItemRepository
				.findByBoxOrder(boxOrder);
		for (BoxOrderItem item : items) {
			amount += this.calcBoxOrderItemAmount(item);
		}

		return amount;
	}

	private double calcBoxOrderItemAmount(BoxOrderItem item) {
		double amount = 0.0;
		amount += item.getPrice() * item.getPriceWeight();
		return amount;
	}

	@Override
	public List<MonthlyAmountVo> findOtherAvailableClients(Client srcClient,
			double toAddAmount) {

		List<MonthlyAmountVo> monthlyAmountVos = new ArrayList<MonthlyAmountVo>();
		Client parentClient = srcClient.getParent() != null ? srcClient
				.getParent() : srcClient;
		List<Client> clients = this.clientRepository.findByParent(parentClient);

		for (Client client : clients) {

			MonthlyAmountVo vo = this.calcMonthlyAmount(client);

			if (vo.getQuotaAmount() - (vo.getCumulatedAmount() + toAddAmount) >= 0) {
				monthlyAmountVos.add(vo);
			}
		}

		return monthlyAmountVos;
	}

}
